package Practica;

import es.ucm.fdi.plg.evlib.Atribucion;
import es.ucm.fdi.plg.evlib.Atributo;
import es.ucm.fdi.plg.evlib.LAtributo;
import es.ucm.fdi.plg.evlib.SemFun;
import es.ucm.fdi.plg.evlib.TAtributos;
import java.util.HashMap;
import java.util.Map;



class Asignacion implements SemFun{

    @Override
    public Object eval(Atributo... args) {
        return args[0].valor();
    }
    
}
    class Asignacion0 implements SemFun{

        @Override
        public Object eval(Atributo... args) {
            return 0;
        }

}
    

    class AsignacionSuma1 implements SemFun{

        @Override
        public Object eval(Atributo... args) {
            int i=(int)args[0].valor();
            i=i+1;
        	return i;
        }

}
    class AsignacionSuma2 implements SemFun{

        @Override
        public Object eval(Atributo... args) {
            int i = (int)args[0].valor();
        	i=i+2;
            return i;
        }

}
class AsignacionSuma3 implements SemFun{

        @Override
        public Object eval(Atributo... args) {
        	int i=(int) args[0].valor();
        	i=i+3;
        	return i;
        }

}
    class AsignacionWrite implements SemFun{

        @Override
        public Object eval(Atributo... args) {
            String i=(String)args[0].valor();
        	return "apila_str("+i +") escribe";
        }

}

class ConcatenaI implements SemFun{
	
        @Override
        public Object eval(Atributo... args) {
        	
        String string1=(String)args[0].valor();
        
        String string3=(String)args[2].valor();
        
        String string5=(String)args[4].valor();
        int i1=((int)args[1].valor())+1;
        int i2=((int)args[3].valor());
        return string1+" ir_f("+i1+") "+string3+" ir_a("+i2+") "+string5;
        }

}
class ConcatenaE implements SemFun{
	
    @Override
    public Object eval(Atributo... args) {
    	
    	String string1=(String)args[0].valor();
        int i1= ((int)args[1].valor());
        String string3=(String)args[2].valor();
    	return string1+" copia "+" ir_v("+i1+") "+" desapila "+string3;
    
    }

}
class ConcatenaT implements SemFun{
	
    @Override
    public Object eval(Atributo... args) {
    	
    	String string1= (String) args[0].valor();
    	int i1= ((int)args[1].valor());
    	String string2= (String) args[2].valor();
	return string1+" copia "+" ir_f("+i1+") "+" desapila "+string2;
    
    }

}
class ConcatenaFTRUE implements SemFun{
	
    @Override
    public Object eval(Atributo... args) {
    	
	return "apila_cierto()";
    
    }

}
class ConcatenaFFALSE implements SemFun{
	
    @Override
    public Object eval(Atributo... args) {
	return "apila_falso()";
    }

}
class Asignacion2 implements SemFun{

    @Override
    public Object eval(Atributo... args) {

    	return args[0].valor();
    }
    
}

class concatena2cod implements SemFun{
	
    @Override
    public Object eval(Atributo... args) {
    	
    	String string1= (String) args[0].valor();
    	String string2= (String) args[2].valor();
	return string1+string2;
    
    }

}


public class EAtribucion extends Atribucion {    
    
    // Se crean los objetos que representan las diferentes funciones semánticas
    private static SemFun concatena2cod = new concatena2cod();
    private static SemFun asignacion0 = new Asignacion0();
    // Se especifican las funciones de atribución que se emplearán en la definición 
    // CUP. Estas habrá que substituirlas por las correctas, programadas
    // según los patrones dados en clase
   
   
    public TAtributos prog(String id, TAtributos declaraciones, TAtributos instrucciones) {
       regla("PROG -> PROGRAM : identificador {Declaraciones Instrucciones}");
       
       TAtributos p = atributosPara("PROG", "cod");
       Atributo astring= atributoLexicoPara("STRING","lex",id);
       
       dependencias(p.a("cod"), astring);
       dependencias(p.a("cod"), declaraciones.a("cod"),instrucciones.a("cod") );
       
       calculo(p.a("cod"), concatena2cod);
        return p;
    } 

    public TAtributos decla() {
        regla("Declaraciones →  ");
        
        TAtributos decla = atributosPara("DECLARACIONES", "cod");
        
        
        //dependencias(p.a("cod"), astring);
        //dependencias(p.a("cod"), declaraciones.a("cod"),instrucciones.a("cod") );
        
        calculo(decla.a("cod"), asignacion0);
         return decla;
     } 
    
    public TAtributos instruc() {
        regla("Instruccionesones →  ");
        
        TAtributos instruc = atributosPara("INSTRUCCIONES", "cod");
        //Atributo astring= atributoLexicoPara("STRING","lex",id);
        
        //dependencias(p.a("cod"), astring);
        //dependencias(p.a("cod"), declaraciones.a("cod"),instrucciones.a("cod") );
        
        calculo(instruc.a("cod"), asignacion0);
         return instruc;
     } 
}





